home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / qex / qexsndcd / cw250.cpp next >
Text File  |  1994-07-06  |  7KB  |  186 lines

  1. // --------------------------------------------------------------------
  2. //      Super Duper DSP CW filter - Control and User Interface    
  3. //      Demo software accompanying the QEX August 1994 article:           
  4. //      "Programming a DSP PC Sound Card for Amateur Radio"         
  5. //                  (c) Johan Forrer, KC7WW                   
  6. //             26553 Priceview Drive                             
  7. //                    Monroe, OR 97456                       
  8. // --------------------------------------------------------------------
  9. //                                       
  10. //     Compilation/link instructions for Borland C++ 4.0                                  
  11. //     >bcc -c -ml -O2 -Z -G cw250.cpp
  12. //     >tlink /x c:\bc4\lib\c0l cw250 PSA1.obj PSA2.obj, emu mathl cl
  13. //                                       
  14. // --------------------------------------------------------------------
  15. //              This is how the AD1848 is reprogrammed:
  16. // --------------------------------------------------------------------
  17. // Idx=0
  18. // Sta=0
  19. //  0 =47    select left  line, gain =7
  20. //  1 =47    select right line, gain =7
  21. //  2 =0x80  mute left  aux#1
  22. //  3 =0x80  mute right aux#1
  23. //  4 =0x80  mute left  aux#2
  24. //  5 =0x80  mute right aux#2
  25. //  6 =0x07  left  DAC with some attenuation
  26. //  7 =0x07  right DAC with some attenuation
  27. //  8 =0x51  16 bit 2s compl, linear PCM, stereo, 
  28. //           xtal1=16.93MHz, 5512.5 kHz,
  29. //  9 =0x08  DMA capture/playback, Autocalibrate after mode change,
  30. //           disable capture/playback, dual DMA mode
  31. // 10 =0     N.A
  32. // 11 =0     N.A
  33. // 12 =0     N.A
  34. // 13 =0     digital mix muted
  35. // 14 =0     base count = 0
  36. // 15 =0     base count = 0
  37. // --------------------------------------------------------------------
  38.  
  39. #include "psa.h"
  40.  
  41. // --------------------------------------------------------------------
  42. // Local function prototypes
  43. // --------------------------------------------------------------------
  44. void start_application(char *, unsigned char *);
  45. void terminate_application(void);
  46. void timer_test(void);
  47.  
  48. int tick;              // a global tick counter
  49.  
  50. #define MON "cwmon.ld"         // define name of bootstrap
  51. #define APP "cw250.cde"        // define name of application
  52.  
  53. void main()
  54. {
  55. unsigned int boot_version;
  56. unsigned char initstate[18]={0,0,0x47,0x47,0x80,0x80,0x80,
  57.         0x80,0x07,0x07,0x51,0x08,0,0,0,0,0,0};
  58.  
  59. // -------------------------------------------------------------------------
  60. // Announce who we are and what the program is about
  61. // -------------------------------------------------------------------------
  62.     printf("Demo program to set up and communicate with a PSA sound card\n");
  63.     printf("By Johan Forrer, KC7WW\n\n");
  64.  
  65. // -------------------------------------------------------------------------
  66. // Check for presence and initialze DSP card
  67. // -------------------------------------------------------------------------
  68.     if (!checkDSPcard(pssbase, wssbase)) {
  69.         printf("No PSA card - or WSS address is not available\n");
  70.         exit(0);
  71.         }
  72.  
  73. // -------------------------------------------------------------------------
  74. // Perform the DSP bootstrap next
  75. // and verify that it has completed successfully
  76. // -------------------------------------------------------------------------
  77.     boot_version=bootdsp(MON, NULL, (unsigned)16000);
  78.     checkdsptestprog();
  79.     printf("Monitor version %d.%d reported\n", 
  80.         boot_version>>8, boot_version&0x0F);
  81.  
  82. // -------------------------------------------------------------------------
  83. // Finally we are ready to load and run the DSP application
  84. // also start the timer
  85. // -------------------------------------------------------------------------
  86.     start_application(APP, initstate);
  87.     timer_test();
  88.     terminate_application();
  89. }
  90.  
  91. //---------------------------------------------------------------------------
  92. //                    Some local functions
  93. //---------------------------------------------------------------------------
  94. //---------------------------------------------------------------------------
  95. // Start application
  96. //---------------------------------------------------------------------------
  97. void start_application(char *app_name, unsigned char ad1848_state[])
  98. {
  99.  
  100.     load_DSP_mem(app_name);       // load the DSP application code
  101.  
  102.     set1848state(ad1848_state); // reprogram CODEC
  103.  
  104.     outp(wssbase+WSS_CODECINDEXADDR,0x0009); // Capture/Playback on
  105.     outp(wssbase+WSS_CODECINDEXDATA,0x0003); 
  106.  
  107.     putdspword(0x00b4);        // send "start application" code to DSP 
  108.  
  109. }
  110.  
  111. //---------------------------------------------------------------------------
  112. // Terminate application
  113. //---------------------------------------------------------------------------
  114. void terminate_application()
  115. {
  116.  
  117.     putdspword(0x00b5);    // send "stop application" code to DSP
  118.  
  119.     outp(wssbase+WSS_CODECINDEXDATA,0x0009); // Playback/capture off 
  120.     outp(wssbase+WSS_CODECINDEXDATA, 0);
  121.  
  122.     outp(wssbase+WSS_CODECINDEXADDR,0x0006);  // mute DAC
  123.     outp(wssbase+WSS_CODECINDEXDATA, 0xDF);
  124.     outp(wssbase+WSS_CODECINDEXADDR,0x0007);
  125.     outp(wssbase+WSS_CODECINDEXDATA, 0xDF);
  126.  
  127. }
  128.  
  129. //--------------------------------------------------------------------------
  130. // Timer test using interrupt IRQ7
  131. //--------------------------------------------------------------------------
  132. void timer_test()
  133. {
  134.  
  135. // Define ISR prototypes
  136. void interrupt (*oldfunc)(...);        // for storage of old vector
  137. void interrupt DSP_int_serv(...);      // Prototype for new interrupt serv.
  138. unsigned char old_IMR;            // Save old PIC IMR
  139.  
  140.     tick=0;
  141.     printf("Timer is now ticking - hit any key to stop application\n ");
  142.  
  143.     oldfunc=getvect(INT);        // Hook IRQ7 on the PC side
  144.     setvect(INT,DSP_int_serv);
  145.  
  146. // Set INT7 on DSP side as well
  147.     outpw(pssbase+PSS_CONFIG,IRQ7);
  148.     old_IMR=inp(0x21);        // get IMR
  149.     outp(0x21,old_IMR&0x7F);    // Arm PC's IRQ7 in IMR
  150.  
  151.     putdspword(0x00b0);        // send "start timer" code to DSP
  152.  
  153. // Show timer ticks, check when user quits 
  154.     for(;;) {
  155.         if(kbhit()) break;
  156.         if(tick) {
  157.             printf(".");
  158.             tick=0;
  159.             }
  160.         }
  161.  
  162.     getch();            // flush out breakout charater
  163.  
  164.     putdspword(0x00b1);             // send "stop timer" code to DSP
  165.  
  166.     outpw(pssbase+PSS_IRQ_ACK, 0);    // Clear any pending PSA interrupts
  167.     outpw(pssbase+PSS_CONFIG,0x0000);  // Remove PSA from IRQ7
  168.  
  169.     outp(0x21,old_IMR);        // Restore IMR
  170.  
  171.     setvect(INT, oldfunc);        // Restore INT
  172.  
  173.     printf("\nApplication terminated\n");
  174. }    
  175.  
  176. //--------------------------------------------------------------------------
  177. // The new IRQ7 interrupt handler
  178. //--------------------------------------------------------------------------
  179. void interrupt DSP_int_serv(...)
  180. {
  181.     outpw(pssbase+PSS_IRQ_ACK, 0);    // Clear the interrupt
  182.     outp(0x20,0x20);         // write EOI to PIC 
  183.                     // else bad things happen!
  184.     tick++;
  185. }
  186.